<template>
  <div class="app-container bg-gray" v-loading="loading">
    <div class="head bg-white">
      <el-row v-if="type == '新建'">
        <div class="d-flex ai-center">
          <div class="flex-1">{{ groupInfo.groupName }}</div>
          <el-button type="primary" @click="handleSave" :disabled="saveAble">保存规则</el-button>
        </div>
      </el-row>
      <el-row v-else type="flex" justify="space-between">
        <el-col :span="12">
          <div class="">
            {{ groupInfo.groupName }}
            <el-button v-show="groupInfo.createBy == userId" type="text" @click="handleViewRuleDetail">
              {{ tabNav == "0" ? "规则详情" : "分群用户" }}
            </el-button>
          </div>
          <div class="space-margin">共{{ groupInfo.totalPeople }}人</div>
        </el-col>
        <el-col :span="12" class="text-right" style="font-size: 14px">
          <el-button v-show="ruleVisible" type="primary" @click="handleSave" :disabled="saveAble">保存规则</el-button>
          <div class="space-margin">{{ groupInfo.updateByName }} 规则创建 {{ groupInfo.updateTime }}</div>
          <div class="space-margin">计算时间：{{ groupInfo.actionTime }}</div>
        </el-col>
      </el-row>
    </div>

    <div class="body">
      <!-- 分群的用户列表 -->
      <transition name="fade-line" @after-leave="ruleVisible = true">
        <div v-show="userVisible">
          <user-group-table :userList="userList"></user-group-table>
          <pagination
            v-show="total > 0"
            :total="total"
            :page.sync="queryParams.currentPage"
            :limit.sync="queryParams.pageSize"
            @pagination="getUserList"
          ></pagination>
        </div>
      </transition>

      <!-- 分群的规则详情 -->
      <transition name="fade-line" @after-leave="userVisible = true">
        <div v-show="ruleVisible">
          <div v-if="groupInfo.groupName">
            <!-- <el-input v-model="groupInfo.groupName" style="width: 200px" placeholder="请输入群名称"></el-input> -->
          </div>
          <div class="d-flex ai-center">
            <h4 class="flex-1">在全部用户中，将满足 {{ conclusionRule }} 条件的用户保存为用户分群</h4>
            <el-button type="primary" icon="el-icon-circle-plus-outline" @click="handleAddRule">添加</el-button>
          </div>

          <div v-for="(item, i) in ruleStructureVue" :key="i">
            <operate-button v-if="isOperate(item)" :alias="item" @click.native="handleToggle(i)"></operate-button>
            <div v-else class="bg-white" style="padding-left: 50px">
              <div v-for="(alias, j) in item" :key="j">
                <operate-button
                  v-if="isOperate(alias)"
                  :alias="alias"
                  @click.native="handleToggle(i, j)"
                ></operate-button>
                <rule-item
                  v-else
                  :alias="alias"
                  :rule="getRuleByAlias(alias)"
                  :configAttributeList="configAttributeList"
                  :saleUsers="saleUsers"
                  :saleManage="saleManage"
                  :groupList="groupList"
                  :isLastChild="j == item.length - 1"
                  @onaddsecondrule="handleAddSecondRule"
                  @onremovesecondrule="handleRemoveRule"
                ></rule-item>
              </div>
            </div>
          </div>
        </div>
      </transition>
    </div>

    <!-- 未保存的弹窗 -->
    <el-dialog title="提示" :visible.sync="popShow" width="30%">
      <span>当前分群未保存，请确认是否退出？</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="popShow = false">取 消</el-button>
        <el-button type="primary" @click="handleLeave">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import {
  getGroupInfo,
  getUserAttributes,
  saveGroupInfo,
  getGroupList,
  getGroupUserList,
  getSalesBySaleType,
} from "@/api/smartRun/groupManage";
import { getSaleUserByName } from "@/api/reviewActivities/pushCode";
import { mapGetters } from "vuex";

import RuleItem from "./RuleItem";
import UserGroupTable from "./UserGroupTable";
import CITYS from "@/utils/config/citys";
import { OPERATOR_BETWEEN, OPERATOR_IN, ALPHABET } from "./operator";

const cityOptions = CITYS.map(item => {
  // let name = item.city.replace("市", "");
  let name = item.city;
  return { value: name, label: name };
});

const OperateButton = {
  props: ["alias"],
  render() {
    return (
      <el-button style="margin: 10px" type={this.alias == "and" ? "primary" : "success"}>
        {this.alias == "and" ? "且" : "或"}
      </el-button>
    );
  },
};
let nextHandler = null;
let unwatchRuleListHandler = null;
export default {
  components: { RuleItem, OperateButton, UserGroupTable },
  name: "groupRules",
  data() {
    return {
      popShow: false,
      loading: false,
      saleUsers: [], //销售人员
      saleManage: [], //销管人员
      ruleTypeOptions: [{ value: "0", label: "用户属性" }, { value: "1", label: "用户分群" }],
      configAttributeList: [], // 配置数据（数据库配置的）
      cityOptions: Object.freeze(cityOptions),
      pageStatue: "0", //0、查看权限；1、可编辑；2、可保存
      groupInfo: {
        groupId: "",
        groupName: "",
        totalPeople: "",
        updateByName: "",
        updateTime: "",
        actionTime: "",
        createBy: "",
      },
      ruleStructure: "", // 规则串（后端用）
      ruleStructureVue: [], // 规则串（前端用）
      ruleList: [
        // {'alias': 'A', "ruleType": '0', "ruleKey": '金额', "ruleOperator": 'between', "ruleValue": ['10', '20'], }
      ],
      conclusionRule: "",
      tabNav: "0",
      userVisible: false,
      ruleVisible: false,
      groupList: [], //数据库已有的所有分群
      userList: [], //该群用户列表
      total: 0,
      queryParams: {
        currentPage: 1,
        pageSize: 10,
      },
      type: "", //当前的操作类型
      isSaved: true, //是否保存
    };
  },
  provide() {
    return {
      cityOptions: this.cityOptions,
      ruleTypeOptions: this.ruleTypeOptions,
    };
  },
  computed: {
    isOperate() {
      return v => {
        return v == "and" || v == "or";
      };
    },
    getRuleByAlias() {
      return alias => {
        return this.ruleList.find(v => alias === v.alias);
      };
    },
    ...mapGetters(["userId"]),
    saveAble() {
      if (!this.groupInfo.groupName) return true;
      return this.ruleList.some(rule => {
        let lastValueAble;
        if (rule.ruleType == "1") {
          lastValueAble = true;
        } else if (rule.ruleType == "0") {
          if (rule.ruleOperator === "is not null" || rule.ruleOperator == "is null") {
            lastValueAble = true;
          } else if (rule.ruleOperator == "between") {
            lastValueAble = Array.isArray(rule.ruleValue) && rule.ruleValue.filter(v => !!v).length == 2;
          } else if (rule.ruleOperator == "in" || rule.ruleOperator == "not in") {
            lastValueAble = Array.isArray(rule.ruleValue) && rule.ruleValue.length > 0;
          } else {
            lastValueAble = !!rule.ruleValue;
          }
        }

        return !rule.ruleType || !rule.ruleKey || !rule.ruleOperator || !lastValueAble;
      });
    },
  },
  created() {
    this.initShow();
  },
  mounted() {},
  destroyed() {
    unwatchRuleListHandler && unwatchRuleListHandler();
    unwatchRuleListHandler = null;
    nextHandler = null;
  },
  watch: {
    ruleStructureVue: {
      handler(newVal) {
        let result = this.joinStructure(newVal);
        this.ruleStructure = result;
        this.conclusionRule = result.replace(/and/g, "且").replace(/or/g, "或");
      },
      immediate: true,
    },
    $route() {
      this.initShow();
    },
  },

  beforeRouteLeave(to, from, next) {
    if (this.isSaved || !this.groupInfo.groupName) {
      next();
    } else {
      next(false);
      this.popShow = true;
      nextHandler = next;
    }
  },

  methods: {
    initShow() {
      const query = this.$route.query;
      this.type = query.type || "新建";

      switch (this.type) {
        case "查看":
          this.tabNav = "0";
          this.userVisible = true;
          this.ruleVisible = false;
          this.groupInfo.groupId = query.groupId;
          this.initGroupDetailInfo(this.groupInfo.groupId);
          this.getUserList({ page: 1 });

          break;
        case "修改":
          this.tabNav = "1";
          this.ruleVisible = true;
          this.userVisible = false;
          this.groupInfo.groupId = query.groupId;
          this.initBaseConfig().then(() => {
            this.initGroupDetailInfo(this.groupInfo.groupId);
          });
          break;

        case "新建":
          this.tabNav = "1";
          this.ruleVisible = true;
          this.userVisible = false;
          this.groupInfo.groupName = query.groupName;
          this.initBaseConfig().then(() => {
            this.handleAddRule();
            this.isSaved = false;
          });

          break;

        default:
          break;
      }
    },
    handleLeave() {
      this.popShow = false;
      nextHandler && nextHandler();
    },
    initBaseConfig() {
      this.loading = true;
      return Promise.all([this.initUserAttr(), this.initSaleUser(), this.initSaleManage(), this.initGroupList()]).then(() => {
        this.loading = false;
      });
    },

    //查询活动审核列表
    getUserList({ page }) {
      this.loading = true;
      getGroupUserList({
        groupId: this.groupInfo.groupId,
        page,
        pageSize: this.queryParams.pageSize,
      }).then(({ code, data }) => {
        this.loading = false;
        if (code == 200) {
          this.queryParams.currentPage = data.pageNum;
          this.total = data.total;

          this.userList = data.list;
        }
      });
    },

    multipleValue(ruleOperator) {
      return ruleOperator == "in" || ruleOperator == "not in" || ruleOperator == "between";
    },

    initGroupDetailInfo(groupId) {
      getGroupInfo({
        groupId,
      }).then(({ code, data }) => {
        if (code == 200) {
          this.groupInfo = {
            groupId: data.groupId,
            groupName: data.groupName,
            totalPeople: data.totalPeople,
            updateByName: data.updateByName,
            updateTime: data.updateTime,
            actionTime: data.actionTime,
            createBy: data.createBy,
          };

          this.ruleStructureVue = JSON.parse(data.ruleStructureVue);
          this.ruleList = data.ruleList.map(item => {
            // 多值场景
            if (!this.multipleValue(item.ruleOperator)) {
              item.ruleValueList = item.ruleValueList[0] || "";
            }
            return {
              alias: item.alias,
              ruleType: item.ruleType,
              ruleKey: item.ruleKey,
              ruleOperator: item.ruleOperator,
              ruleValue: item.ruleValueList,
            };
          });
          this.addWatchRuleChange();
        }
      });
    },

    addWatchRuleChange() {
      if (unwatchRuleListHandler) return;
      unwatchRuleListHandler = this.$watch(
        "ruleList",
        () => {
          this.isSaved = false;
        },
        { deep: true },
      );
    },

    // 保存群规则
    handleSave() {
      let ruleList = this.ruleList.map(item => {
        let ruleValue = Array.isArray(item.ruleValue) ? [...item.ruleValue] : item.ruleValue ? [item.ruleValue] : [];
        let newItem = { ...item, ruleValueList: ruleValue };
        delete newItem.ruleValue;
        return newItem;
      });

      let params = {
        groupName: this.groupInfo.groupName,
        ruleStructureVue: JSON.stringify(this.ruleStructureVue),
        ruleStructure: this.ruleStructure,
        ruleList,
      };
      if (this.groupInfo.groupId) {
        params.groupId = this.groupInfo.groupId;
      }

      this.loading = true;
      saveGroupInfo(params)
        .then(({ code, data }) => {
          this.loading = false;

          if (code == 200) {
            this.$message.success("保存成功！");
            this.isSaved = true;
            if (unwatchRuleListHandler) {
              unwatchRuleListHandler();
              unwatchRuleListHandler = null;
            }
            this.$router.push({
              name: "GroupRules",
              query: { groupId: data.groupId, type: "查看" },
            });
          }
        })
        .catch(() => {
          this.loading = false;
        });
    },
    handleViewRuleDetail() {
      if (this.tabNav == "0") {
        this.tabNav = "1";
        this.userVisible = false;

        if (this.configAttributeList.length == 0) {
          this.initBaseConfig();
        }
      } else {
        this.tabNav = "0";
        this.ruleVisible = false;

        if (this.userList.length == 0) {
          this.getUserList({ page: 1 });
        }
      }
    },

    initGroupList() {
      return getGroupList({
        own: false,
        page: 1,
        pageSize: 999,
      }).then(({ code, data }) => {
        if (code == 200) {
          this.groupList = data.list.map(item => {
            return { label: item.groupName, value: item.groupId };
          });
        }
      });
    },

    // 初始化销售员
    initSaleUser() {
      return getSalesBySaleType({
        saleType: "0",
      }).then(res => {
        let rows = res.data;
        this.saleUsers = rows.map(item => {
          let label = `${item.userName}`;
          return { value: item.agentId, label };
        });
      });
    },

    initSaleManage() {
      return getSalesBySaleType({
        saleType: "1",
      }).then(res => {
        let rows = res.data;
        this.saleManage = rows.map(item => {
          let label = `${item.userName}`;
          return { value: item.agentId, label };
        });
      });
    },

    // 初始化用户属性下拉数据
    initUserAttr() {
      return getUserAttributes().then(({ code, data }) => {
        if (code == 200) {
          this.configAttributeList = data.map(item => {
            let list = item.listClass ? JSON.parse(item.listClass) : [];
            list = list.reduce((result, item) => {
              if (item == "in") {
                result = result.concat(OPERATOR_IN);
              } else if (item == "between") {
                result = result.concat(OPERATOR_BETWEEN);
              }
              return result;
            }, []);

            return {
              value: item.dictValue,
              label: item.dictLabel,
              type: item.cssClass,
              options: JSON.parse(item.remark),
              operates: list,
            };
          });
        }
      });
    },

    handleToggle(i, j = -1) {
      if (j === -1) {
        let r = this.ruleStructureVue[i] == "and" ? "or" : "and";
        this.$set(this.ruleStructureVue, i, r);
      } else {
        let r = this.ruleStructureVue[i][j] == "and" ? "or" : "and";
        this.$set(this.ruleStructureVue[i], j, r);
      }
      this.isSaved = false;
    },
    handleAddRule() {
      let lastItem = this.ruleStructureVue[this.ruleStructureVue.length - 1];
      let nextWord;
      if (lastItem) {
        let word = lastItem[0].charAt(0);
        let newWord = ALPHABET[ALPHABET.indexOf(word) + 1];
        nextWord = newWord;
      } else {
        nextWord = ALPHABET[0];
      }

      this.ruleList.push(this.createRule(nextWord));
      if (this.ruleStructureVue.length) {
        this.ruleStructureVue.push("and", [nextWord]);
      } else {
        this.ruleStructureVue.push([nextWord]);
      }
    },

    createRule(alias) {
      return {
        alias,
        ruleType: "0",
        ruleKey: "",
        ruleOperator: "",
        ruleValue: "",
      };
    },
    handleAddSecondRule(e) {
      let arr = this.ruleStructureVue.find(item => {
        return Array.isArray(item) && item.indexOf(e) > -1;
      });

      if (arr.length == 1 && arr[0].length == 1) {
        let rule = this.ruleList.find(v => v.alias === arr[0]);
        rule.alias = arr[0] + "1";
        let newAlias = arr[0] + "2";
        this.ruleList.push(this.createRule(newAlias));
        arr.splice(0, 1, ...[rule.alias, "or", newAlias]);
      } else {
        let last = arr[arr.length - 1];
        let alias = last.slice(0, 1) + (Number(last.slice(1)) + 1);
        // console.log(arr, alias);

        this.ruleList.push(this.createRule(alias));
        arr.push("or", alias);
      }
    },

    handleRemoveRule(e) {
      // console.log("移除", e);
      let arr = this.ruleStructureVue.find(item => {
        return Array.isArray(item) && item.indexOf(e) > -1;
      });
      let firstIndex = this.ruleStructureVue.indexOf(arr);
      let secondIndex = arr.indexOf(e);

      if (this.ruleStructureVue.length == 1 && arr.length == 1) {
        return this.$message.error("至少保留一条规则");
      }

      this.removeRule(e);

      if (arr.length == 1) {
        this.ruleStructureVue.splice(firstIndex, 1);
        if (firstIndex != 0) {
          this.ruleStructureVue.splice(firstIndex - 1, 1);
        } else {
          this.ruleStructureVue.splice(firstIndex, 1);
        }
      } else {
        arr.splice(secondIndex, 1);
        if (secondIndex != 0) {
          arr.splice(secondIndex - 1, 1);
        } else {
          arr.splice(secondIndex, 1);
        }
      }
      // console.log(this.ruleStructureVue);

      this.aliasReset();
    },

    removeRule(alias) {
      let index = this.ruleList.findIndex(v => alias === v.alias);
      this.ruleList.splice(index, 1);
    },

    joinStructure(list) {
      return list.reduce((result, item) => {
        let str = Array.isArray(item) ? (item.length > 1 ? `(${item.join(" ")})` : item.join(" ")) : item;
        return result ? result + " " + str : str;
      }, "");
    },

    aliasReset() {
      // 规则别名的下标数字重置
      let rules = this.ruleStructureVue.filter(v => Array.isArray(v));
      let result = rules.reduce((result, item) => {
        if (item.length == 1) {
          if (item[0].length != 1) {
            result[item[0]] = item[0].charAt(0);
          }
        } else {
          item
            .filter(v => v !== "and" && v !== "or")
            .forEach((innerItem, i) => {
              result[innerItem] = innerItem[0] + (i + 1);
            });
        }

        return result;
      }, {});

      this.ruleList.forEach(item => {
        if (result[item.alias]) {
          item.alias = result[item.alias];
        }
      });

      this.ruleStructureVue.forEach(item => {
        if (Array.isArray(item)) {
          item.forEach((v, i) => {
            if (v !== "and" && v !== "or") {
              if (result[v]) {
                this.$set(item, i, result[v]);
              }
            }
          });
        }
      });

      // console.log(result);
    },
  },
};
</script>

<style scoped>
.app-container {
  min-height: calc(100vh - 84px);
}
.head {
  padding: 10px;
}

.space-margin {
  margin-top: 10px;
}
.body {
  margin-top: 50px;
}
.pop {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 999;
  font-size: 100px;
  color: white;
  /* display: flex; */
}
.fade-line-enter-active,
.fade-line-leave-active {
  transition: all 0.5s;
}
.fade-line-enter,
.fade-line-leave-to {
  opacity: 0;
  transform: translateX(36px);
}
</style>
